package org.gdstash.ui.util;

import org.gdstash.character.GDChar;
import org.gdstash.character.GDCharSummary;
import org.gdstash.ui.GDStashFrame;
import org.gdstash.util.GDConstants;
import org.gdstash.util.GDMsgFormatter;
import org.gdstash.util.GDMsgLogger;

import java.io.File;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;

public class GDCharInfoList {
    public static List<GDCharFileInfo> gdCharFileInfos;

    public static void findChars(final GDStashFrame frame, final GDCharFileInfo reloadInfo) {
        final List<GDCharFileInfo> infos = GDCharInfoList.gdCharFileInfos;
        GDCharInfoList.gdCharFileInfos = new LinkedList<GDCharFileInfo>();
        if (GDStashFrame.iniConfig == null) {
            return;
        }
        if (GDStashFrame.iniConfig.sectDir.savePath == null) {
            return;
        }
        final String mainDir = GDStashFrame.iniConfig.sectDir.savePath + GDConstants.FILE_SEPARATOR + "main";
        findCharsInDir(mainDir);
        final String modDir = GDStashFrame.iniConfig.sectDir.savePath + GDConstants.FILE_SEPARATOR + "user";
        findCharsInDir(modDir);
        adjustCharInfos(infos, reloadInfo);
        if (frame != null) {
            if (frame.pnlCharEdit != null) {
                frame.pnlCharEdit.refreshCharSelection();
            }
            if (frame.pnlCharInventory != null) {
                frame.pnlCharInventory.refreshCharSelection();
            }
        }
    }

    private static void findCharsInDir(final String charDir) {
        final File file = new File(charDir);
        if (file.isDirectory()) {
            processCharDir(file);
        }
        if (file.isFile()) {
            processCharFile(file);
        }
    }

    private static void processCharDir(final File dir) {
        if (dir == null) {
            return;
        }
        final File[] files = dir.listFiles();
        if (files == null) {
            return;
        }
        for (int i = 0; i < files.length; ++i) {
            final File file = files[i];
            if (file != null) {
                if (file.isDirectory()) {
                    processCharDir(file);
                }
                if (file.isFile()) {
                    processCharFile(file);
                }
            }
        }
    }

    private static void processCharFile(final File file) {
        final String s = file.getName().toUpperCase(GDConstants.LOCALE_US);
        if (s.equals("PLAYER.GDC")) {
            final GDCharSummary gdcSum = GDChar.readCharSummary(file);
            if (gdcSum != null) {
                final File f = file.getParentFile();
                try {
                    String dir = f.getCanonicalPath();
                    final int pos = dir.lastIndexOf(GDConstants.FILE_SEPARATOR);
                    if (pos != -1) {
                        dir = dir.substring(pos + 1);
                    }
                    final GDCharFileInfo info = new GDCharFileInfo();
                    info.charFile = file;
                    info.gdcSummary = gdcSum;
                    GDCharInfoList.gdCharFileInfos.add(info);
                } catch (IOException ex) {
                    GDMsgLogger.addError(ex);
                }
            }
        }
    }

    public static void adjustCharInfo(final GDCharFileInfo info) {
        if (info.gdcSummary == null) {
            return;
        }
        String dir = null;
        try {
            info.fileName = info.charFile.getCanonicalPath();
            final File parent = info.charFile.getParentFile();
            dir = parent.getCanonicalPath();
        } catch (IOException ex) {
            info.fileName = null;
            dir = null;
        }
        String sHC = null;
        String sExp = null;
        if (info.gdcSummary.isHardcore()) {
            sHC = GDMsgFormatter.getString(GDMsgFormatter.rbUI, "TXT_CHAR_HARDCORE_SHORT");
        } else {
            sHC = GDMsgFormatter.getString(GDMsgFormatter.rbUI, "TXT_CHAR_SOFTCORE_SHORT");
        }
        sExp = info.gdcSummary.getExpansionInfo();
        dir = info.charFile.getParentFile().getParentFile().getName();
        final Object[] sArgs = {info.gdcSummary.getCharName(), info.gdcSummary.getClassName(), dir, sHC, sExp, info.gdcSummary.getLevel()};
        String s = GDMsgFormatter.format(GDMsgFormatter.rbUI, "TXT_CHAR_SELECT", sArgs);
        s = "<html>" + s + "</html>";
        info.charInfo = s;
    }

    public static void adjustCharInfos(final List<GDCharFileInfo> infos, final GDCharFileInfo reloadInfo) {
        if (GDCharInfoList.gdCharFileInfos == null) {
            return;
        }
        for (final GDCharFileInfo info : GDCharInfoList.gdCharFileInfos) {
            adjustCharInfo(info);
            if (infos != null) {
                for (final GDCharFileInfo info2 : infos) {
                    if (info.fileName.equals(info2.fileName) && info2.gdChar != null && info2 != reloadInfo && info2.gdChar.hasChanged()) {
                        info.gdChar = info2.gdChar;
                    }
                }
            }
            if (reloadInfo != null && info.fileName.equals(reloadInfo.fileName)) {
                if (info.gdChar == null) {
                    info.gdChar = new GDChar(info.charFile);
                }
                info.gdChar.read();
                if (!info.gdChar.hasErrors()) {
                    continue;
                }
                info.gdChar = null;
            }
        }
    }

    public static String[] getCharInfos() {
        int size = 1;
        if (GDCharInfoList.gdCharFileInfos != null) {
            size += GDCharInfoList.gdCharFileInfos.size();
        }
        final String[] cis = new String[size];
        cis[0] = "";
        if (GDCharInfoList.gdCharFileInfos == null) {
            return cis;
        }
        if (GDCharInfoList.gdCharFileInfos.size() == 0) {
            return cis;
        }
        int i = 1;
        for (final GDCharFileInfo info : GDCharInfoList.gdCharFileInfos) {
            cis[i] = info.charInfo;
            ++i;
        }
        return cis;
    }

    public static void updateCharSummary() {
        if (GDCharInfoList.gdCharFileInfos == null) {
            return;
        }
        for (final GDCharFileInfo info : GDCharInfoList.gdCharFileInfos) {
            if (info.gdcSummary == null) {
                continue;
            }
            info.gdcSummary.updateClassName();
            adjustCharInfo(info);
        }
    }

    public static class GDCharFileInfo {
        public File charFile;
        public String fileName;
        public GDCharSummary gdcSummary;
        public String charInfo;
        public GDChar gdChar;
    }
}
